#include <stdio.h>
#include <mpx_supt.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#define BUFFER_SIZE 200
#define DEFAULT_DIRECTORY "."
#define DISPLAY_AT_A_TIME 2
#define MAX_ARGS 20
#define NUM_FUNCTIONS 5
#define COMMAND_LENGTH 20

void diagnostics (int argc, char **argv, char *command) {

	int i;

	printf("\nCommand is: %s\n", command);
	printf("Number of args: %d\n\n", argc);

	for (i=0; i < argc; i++)

		printf("Arg %d is: %s\n", i+1, argv[i]);

	printf("\n");
}

void help (int argc, char **argv) {

	argc=argc;
	argv=argv;
	
}

void date (int argc, char **argv) {

	argc=argc;
	argv=argv;

}

void version (int argc, char **argv) {

	argc=argc;
	argv=argv;

	printf("\nThe version of MPX you are using is: Module R1.\n\n");

}

void directory (int argc, char **argv) {
	char *directory;
	int  result;
	
	if (argc > 1) {
		printf("\n\tusage: directory {path}\n\n");
		return;
	}
	
	// Attempt to open the user's requested directory.
	directory = (argc == 0 ? DEFAULT_DIRECTORY : argv[0]);
	result = sys_open_dir(directory);

	// If the attempt succeeded, print the files in the directory and their
	// sizes to the standard output.
	if (result == OK) {
		char  filename[BUFFER_SIZE];
		int   written = 0;
		short pause = 0;
		long  file_size;

		while (
			sys_get_entry(
				filename,
				BUFFER_SIZE,
				&file_size
			) != ERR_SUP_NOENTR
		) {
			// If a specific number of lines have been printed, pause the
			// printing so the user can catch up.
			if (pause) {
				system("pause");
				gotoxy(1, wherey() - 2);
				printf("                               ");
				gotoxy(1, wherey());
				pause = 0;
			}

			// Write the file and its size to the terminal.
			printf("%s    %d bytes\n", filename, file_size);

			// If a specific number of lines have been printed, set the pause
			// flag.
			if ((++written % DISPLAY_AT_A_TIME) == 0) {
				pause = 1;
			}
		}

		// If no files were printed, write a message to the screen.
		if (written == 0) {
			printf("No .MPX files were found in the directory.");
		}

		// Clear after the output.
		printf("\n\n");
	}
	
	// Otherwise, print error messages explaining the failure.
	else {
		switch (result) {
			case ERR_SUP_DIROPN:
				printf(
					"\n\tError: could not open the directory \"%s\".\n\n",
					directory
				);
				break;
				
			case ERR_SUP_INVDIR:
				printf(
					"\n\tError: \"%s\" is an invalid directory.\n\n",
					directory
				);
				break;
		}
	}
}

void quit (int argc, char **argv) {

	argc=argc;
	argv=argv;

	printf("\nThanks for using MPX.\n\n");
	system("pause");
	sys_exit();

}

void run () {

	int found;
	char buffer[BUFFER_SIZE];
	char separator[]=" ";
	char *command, *token;
	int size=BUFFER_SIZE;
	int numargs=0;
	int i;
	char *args[MAX_ARGS];

	char function_names[NUM_FUNCTIONS][COMMAND_LENGTH] = {"help", "version", "date", "directory", "quit"};
	int (*functions[NUM_FUNCTIONS])(int, char**) = {help, version, date, directory, quit};

	system("cls");
	printf("Welcome to MPX. Each command accepts up to 50 args expressed in 200 characters or less.\n \nType a command to begin:\n\n");

	while (1) {

		numargs=0;

		printf("> ");
		sys_req(READ, TERMINAL, buffer, &size);
		buffer[strlen(buffer)-1]='\0';
		command = strtok(buffer, separator);

		token = strtok (NULL, separator);

		while (token != NULL) {
			numargs++;
			args[numargs-1]=token;
			token = strtok(NULL,separator);
		}

		// diagnostics(numargs, args, command);

		found=0;

		for (i = 0; i < NUM_FUNCTIONS; i++) {

		       if (strcmp(function_names[i], command) == 0) {
			       functions[i](numargs, args);
			       found=1;
		       }
		}

		if (found == 0)
			printf("\nSorry, but the command you entered, \"%s\", seems to be unimplemented.\n\n", command);

	}

}

int main () {

	sys_init(MODULE_R1);
	run();
	return 0;
}